home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 August: Tool Chest / Dev.CD Aug 94.toast / New System Software Extensions / OpenDoc A6 / OpenDoc Parts Framework / OPF / OS / FWMemory / Sources / FWMemMgr.cpp < prev    next >
Encoding:
Text File  |  1994-04-21  |  17.7 KB  |  589 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWMemMgr.cpp
  4. //    Release Version:    $ 1.0d1 $
  5. //
  6. //    Creation Date:        3/28/94
  7. //
  8. //    Copyright:    © 1993, 1994 by Apple Computer, Inc., all rights reserved.
  9. //
  10. //========================================================================================
  11.  
  12. #ifndef   FWMEMMGR_H
  13. #include "FWMemMgr.h"
  14. #endif
  15.  
  16. #ifndef FWEXCDEF_H
  17. #include "FWExcDef.h"
  18. #endif
  19.  
  20. #ifndef   FWMEMTAS_H
  21. #include "FWMemTas.h"
  22. #endif
  23.  
  24. #ifndef FWOBJECH_H
  25. #include "FWObjecH.h"
  26. #endif
  27.  
  28. #if defined(FW_BUILD_MAC) && !defined(__OSUTILS__)
  29. #include <OSUtils.h>
  30. #endif
  31.  
  32. #if defined(FW_BUILD_MAC) && !defined(__MEMORY__)
  33. #include <Memory.h>
  34. #endif
  35.  
  36. #if defined(FW_BUILD_WIN) && !defined(_INC_WINDOWS)
  37. #include <Windows.h>
  38. #endif
  39.  
  40. #if defined(FW_BUILD_WIN) && !defined(_INC_WINDOWSX)
  41. #include <WindowsX.h>
  42. #endif
  43.  
  44. #include <string.h>
  45.  
  46. #pragma segment MemoryManagerPackage
  47.  
  48. #if defined(__SC__) && defined(FW_BUILD_WIN)
  49.  
  50. #if !defined(__LIMITS_H)
  51. #include <limits.h>
  52. #endif
  53.  
  54. #if !defined(__HUGEPTR_H) && defined(FW_BUILD_WIN16)
  55. #include <hugeptr.h>
  56. #endif
  57.  
  58. #endif
  59.  
  60. _FW_EXCEPTION_IMPLEMENT(FW_XMemoryExhausted, FW_XPrivException)
  61.  
  62. #define PRIV_CLEAR_MEM_ON_ALLOC
  63.  
  64. // It'd be cool to let this be set at program startup using InitializationFile setting
  65. #ifdef PRIV_CLEAR_MEM_ON_ALLOC
  66. const unsigned char kKnownRawByte = 0;
  67. #else
  68. const unsigned char kKnownRawByte = 0x5A;
  69. #endif
  70.  
  71. //========================================================================================
  72. // Global procedures
  73. //========================================================================================
  74.  
  75. #ifdef FW_BUILD_MAC
  76. //----------------------------------------------------------------------------------------
  77. // SetStackSpace
  78. //----------------------------------------------------------------------------------------
  79.  
  80. void SetStackSpace(long numBytes)
  81. {
  82.     long newLimit;
  83.  
  84.     newLimit = (long)GetCurrentStackBase() - numBytes;
  85.     if ((long)GetApplLimit() > newLimit)
  86.         SetApplLimit((Ptr)newLimit);
  87. }
  88. #endif
  89.  
  90.  
  91. #ifdef FW_BUILD_MAC
  92. //----------------------------------------------------------------------------------------
  93. // MacGrowZoneProc
  94. //----------------------------------------------------------------------------------------
  95.  
  96. pascal long MacGrowZoneProc(Size /* cbNeeded */)
  97. {
  98.     Debugger(); // We ran out of fMemory
  99.     return 0;
  100. }
  101. #endif
  102.  
  103. #if defined(FW_BUILD_WIN) && defined(FW_qUsePlatformAlloc)
  104. //----------------------------------------------------------------------------------------
  105. // GetPointer
  106. //----------------------------------------------------------------------------------------
  107.  
  108. void*  GetPointer(HANDLE h)
  109. {
  110.     return (void*)::GlobalLock(h);
  111. }
  112. #endif
  113.  
  114. #if defined(FW_BUILD_WIN) && defined(FW_qUsePlatformAlloc)
  115. //----------------------------------------------------------------------------------------
  116. // GetHandle
  117. //----------------------------------------------------------------------------------------
  118.  
  119. HANDLE GetHandle(void* p)
  120. {
  121.     return p != NULL ? GlobalPtrHandle(p) : NULL;
  122. }
  123. #endif
  124.  
  125. //----------------------------------------------------------------------------------------
  126. // set_new_handler
  127. //----------------------------------------------------------------------------------------
  128.  
  129. FW_PFVV set_new_handler(FW_PFVV handler)
  130. {
  131.     FW_SPrivMemoryGlobals& globals = FW_CMemoryTaskGlobals::GetMemoryGlobals();
  132.     FW_PFVV oldHandler = globals.gNewHandler;
  133.     globals.gNewHandler = handler;
  134.     return oldHandler;
  135. }
  136.  
  137. //========================================================================================
  138. // CLASS FW_XMemoryExhausted
  139. //========================================================================================
  140.  
  141. //----------------------------------------------------------------------------------------
  142. // FW_XMemoryExhausted::~FW_XMemoryExhausted 
  143. //----------------------------------------------------------------------------------------
  144. FW_XMemoryExhausted::~FW_XMemoryExhausted()
  145. {
  146. }
  147.  
  148.  
  149. //========================================================================================
  150. // CLASS FW_CMemoryManager
  151. //========================================================================================
  152.  
  153. //----------------------------------------------------------------------------------------
  154. // FW_CMemoryManager::GetMemoryHeap
  155. //----------------------------------------------------------------------------------------
  156.  
  157. FW_CMemoryHeap* FW_CMemoryManager::GetMemoryHeap()
  158. {
  159.     FW_CMemoryHeap* heap = FW_CMemoryTaskGlobals::GetMemoryGlobals().gMemoryHeap;
  160.     FW_ASSERT(heap != NULL);
  161.     
  162.     return heap;
  163. }
  164.  
  165. //----------------------------------------------------------------------------------------
  166. // FW_CMemoryManager::DefaultNewHandler
  167. //----------------------------------------------------------------------------------------
  168.  
  169. void FW_CMemoryManager::DefaultNewHandler()
  170. {
  171.     unsigned long lastRequested = FW_CMemoryTaskGlobals::GetMemoryGlobals().gLastRequested;
  172.     FW_THROW(FW_XMemoryExhausted(lastRequested));
  173. }
  174.  
  175. //----------------------------------------------------------------------------------------
  176. // FW_CMemoryManager::PrimitiveAllocateBlock
  177. //----------------------------------------------------------------------------------------
  178.  
  179. void* FW_CMemoryManager::PrimitiveAllocateBlock(unsigned long n)
  180. {
  181.     void* p;
  182.     
  183. #if !defined FW_qUsePlatformAlloc
  184.     p = GetMemoryHeap()->Allocate(n);
  185. #elif defined FW_BUILD_WIN
  186.     // [?KVV]    Windows hack: Zortech IOStream package contains a bug: it only checks
  187.     //             the offset part of pointers returned from malloc.  This can causes a
  188.     //            problem when we use GlobalLock, since it returns pointers that have
  189.     //            offset == 0!  To work around this bug, we make sure the offset is
  190.     //            never zero
  191.     p = (void*) ((char *) GlobalAllocPtr(GHND, n + 1)) + 1);
  192. #elif defined FW_BUILD_MAC
  193.     p = ::NewPtr((long) n);
  194. #endif
  195.  
  196.     return p;
  197. }
  198.  
  199. //----------------------------------------------------------------------------------------
  200. // FW_CMemoryManager::PrimitiveResizeBlock
  201. //----------------------------------------------------------------------------------------
  202.  
  203. void* FW_CMemoryManager::PrimitiveResizeBlock(void* p, unsigned long n)
  204. {
  205.     void* newP;
  206.     
  207. #if !defined FW_qUsePlatformAlloc
  208.     newP = GetMemoryHeap()->Reallocate(p, n);
  209. #elif defined FW_BUILD_WIN
  210.     HANDLE h  = GetHandle((char*) p - 1);
  211.     ::GlobalUnlock(h);
  212.     HANDLE h2 = ::GlobalReAlloc(h, n + 1, GHND);
  213.     
  214.     if(h2 != NULL)
  215.         newP = (void*) ((char*) GetPointer(h2) + 1);
  216.     else
  217.         newP = NULL;
  218.       
  219.     GetPointer(h);
  220. #elif defined FW_BUILD_MAC
  221.     void *q = p;
  222.     ::SetPtrSize((Ptr) q, n);
  223.     if (MemError() != noErr)
  224.     {
  225.         q = PrimitiveAllocateBlock(n);
  226.         if (q)
  227.         {
  228.             CopyMemory(p, q, n);
  229.             PrimitiveFreeBlock(p);
  230.         }
  231.     }
  232.     newP = q;
  233. #endif
  234.  
  235.     return newP;
  236. }
  237.  
  238. //----------------------------------------------------------------------------------------
  239. // FW_CMemoryManager::PrimitiveGetBlockSize
  240. //----------------------------------------------------------------------------------------
  241.  
  242. unsigned long FW_CMemoryManager::PrimitiveGetBlockSize(void* p)
  243. {
  244.     unsigned long blockSize;
  245.     
  246. #if !defined FW_qUsePlatformAlloc
  247.     blockSize = GetMemoryHeap()->BlockSize(p);
  248. #elif defined FW_BUILD_WIN
  249.     HANDLE h  = GetHandle((char*) p - 1);
  250.     blockSize = ::GlobalSize(h) - 1;
  251. #elif defined FW_BUILD_MAC
  252.     blockSize = ::GetPtrSize(p);
  253. #endif
  254.  
  255.     return blockSize;
  256. }
  257.  
  258. //----------------------------------------------------------------------------------------
  259. // FW_CMemoryManager::PrimitiveFreeBlock
  260. //----------------------------------------------------------------------------------------
  261.  
  262. void FW_CMemoryManager::PrimitiveFreeBlock(void* p)
  263. {
  264. #if !defined FW_qUsePlatformAlloc
  265.     GetMemoryHeap()->Free(p);
  266. #elif defined FW_BUILD_WIN
  267.     GlobalFreePtr((char*) p - 1);
  268. #elif defined FW_BUILD_MAC
  269.     if (p != NULL)
  270.         ::DisposPtr(p);
  271. #endif
  272. }
  273.  
  274. //----------------------------------------------------------------------------------------
  275. // FW_CMemoryManager::AddOffsetToPointer
  276. //----------------------------------------------------------------------------------------
  277.  
  278. void *FW_CMemoryManager::AddOffsetToPointer(void *pointer, unsigned long Offset)
  279. {
  280. #if defined(FW_BUILD_MAC) || defined(FW_BUILD_WIN32S)
  281.     return (void *)((char *)pointer + Offset);
  282. #elif defined(__SC__) && defined(FW_BUILD_WIN16)
  283.     // If 'Offset' is not less than the maximum signed LONG Value, consider it an fError.
  284.     // We could program for these cases, but it is More than likely an fError.
  285.     FW_ASSERT(Offset < (unsigned long)LONG_MAX);
  286.     
  287.     // Symantec C++ note: hugeptr_add(p,o) is a macro that calls the function:
  288.     //        hugeptr_add(p, sizeof(*p) * o)
  289.     // Thus, the pointer passed to hugeptr_add() must be 'char *' type.
  290.     char * typedPointer                = pointer;
  291.     signed long signedLongOffset    = Offset;
  292.     
  293.     // The call to hugeptr_add() is not scoped with '::' because Symantec C++
  294.     // first uses a macro and the macro fails to compile when scoped with '::'.
  295.     return hugeptr_add(typedPointer, signedLongOffset);
  296. #endif
  297. }
  298.  
  299. //----------------------------------------------------------------------------------------
  300. // FW_CMemoryManager::CopyMemory - 
  301. //----------------------------------------------------------------------------------------
  302. void FW_CMemoryManager::CopyMemory(const void* const source,
  303.                                    void* const destination,
  304.                                    unsigned long bytesToMove)
  305. {
  306.     FW_ASSERT(source != 0);
  307.     FW_ASSERT(destination != 0);
  308.  
  309. #ifdef FW_BUILD_WIN
  310.     ::hmemcpy((void*)destination, (void*)source, bytesToMove);
  311. #endif
  312.  
  313. #ifdef FW_BUILD_MAC
  314.     ::BlockMove(source, destination, bytesToMove);
  315. #endif
  316.  
  317. }
  318.  
  319. //----------------------------------------------------------------------------------------
  320. // FW_CMemoryManager::SetMemory - 
  321. //----------------------------------------------------------------------------------------
  322. void FW_CMemoryManager::SetMemory(void *aBlock,
  323.                                       unsigned long bytesToSet,
  324.                                       unsigned char byteValue)
  325. {
  326.     FW_ASSERT(aBlock != 0);
  327.  
  328. #ifdef FW_BUILD_WIN16
  329.     // memset is limited to 64K bytes -- need huge version ???JEL
  330.     FW_ASSERT(bytesToSet <= (size_t)0xFFFFFFFF);
  331. #endif
  332.  
  333.     //::memset(aBlock, byteValue, (size_t) bytesToSet);
  334. }
  335.  
  336. //----------------------------------------------------------------------------------------
  337. // InitializeRawBlock - Set a raw block of fMemory to known values.
  338. //----------------------------------------------------------------------------------------
  339. void FW_CMemoryManager::InitializeRawBlock(void *aBlock, unsigned long sizeBlock)
  340. {
  341. #ifdef FW_DEBUG
  342.     SetMemory(aBlock, sizeBlock, kKnownRawByte);
  343. #endif
  344. }
  345.  
  346. //----------------------------------------------------------------------------------------
  347. // FW_CMemoryManager::AllocateBlock - Allocate a non-relocatable block of fMemory.
  348. //----------------------------------------------------------------------------------------
  349. void* FW_CMemoryManager::AllocateBlock(unsigned long bytesRequested)
  350. {
  351.     FW_LOG_OR_TRIGGER_EXCEPTION(FW_XMemoryExhausted, FW_XMemoryExhausted(bytesRequested));
  352.  
  353.     unsigned long bytesNeeded = bytesRequested;
  354.     void* aBlock = PrimitiveAllocateBlock(bytesNeeded);
  355.     if (aBlock == 0)
  356.         FW_THROW(FW_XMemoryExhausted(bytesRequested));
  357.  
  358.     InitializeRawBlock(aBlock, bytesNeeded);
  359.  
  360.     return aBlock;
  361. }
  362.  
  363. //----------------------------------------------------------------------------------------
  364. // FW_CMemoryManager::ResizeBlock - Resize a non-relocatable block of fMemory.  The
  365. //    block may be moved to a new location if necessary.
  366. //----------------------------------------------------------------------------------------
  367. void *FW_CMemoryManager::ResizeBlock(void *aBlock, unsigned long bytesRequested)
  368. {
  369.     FW_LOG_OR_TRIGGER_EXCEPTION(FW_XMemoryExhausted, FW_XMemoryExhausted(bytesRequested));
  370.  
  371.     unsigned long bytesNeeded = bytesRequested;
  372.     
  373.     void *newBlock;
  374.     if (aBlock == 0)
  375.         newBlock = PrimitiveAllocateBlock(bytesNeeded);
  376.     else
  377.         newBlock = PrimitiveResizeBlock(aBlock, bytesNeeded);
  378.  
  379.     if (newBlock == 0)
  380.         FW_THROW(FW_XMemoryExhausted(bytesRequested));
  381.  
  382.     FW_ASSERT(GetBlockSize(newBlock) >= bytesRequested);
  383.     
  384.     return newBlock;
  385. }
  386.  
  387. //----------------------------------------------------------------------------------------
  388. // FW_CMemoryManager::FreeBlock - Return a non-relocatable block to the free store.
  389. //----------------------------------------------------------------------------------------
  390. void FW_CMemoryManager::FreeBlock(void *aBlock)
  391. {
  392.     if (aBlock != 0)
  393.         PrimitiveFreeBlock(aBlock);
  394. }
  395.  
  396. //----------------------------------------------------------------------------------------
  397. // FW_CMemoryManager::GetBlockSize - Return the size of a non-relocatable block.
  398. //----------------------------------------------------------------------------------------
  399. unsigned long FW_CMemoryManager::GetBlockSize(void *aBlock)
  400. {
  401.     FW_ASSERT(aBlock != 0);
  402.  
  403.  
  404.     return PrimitiveGetBlockSize(aBlock);
  405. }
  406.  
  407. //----------------------------------------------------------------------------------------
  408. // FW_CMemoryManager::AllocateSystemHandle - 
  409. //----------------------------------------------------------------------------------------
  410. FW_PlatformHandle FW_CMemoryManager::AllocateSystemHandle(unsigned long bytesNeeded)
  411. {
  412.     FW_LOG_OR_TRIGGER_EXCEPTION(FW_XMemoryExhausted, FW_XMemoryExhausted(bytesNeeded));
  413.  
  414.     FW_PlatformHandle aSystemHandle;
  415.  
  416. #ifdef FW_BUILD_MAC
  417.     aSystemHandle = ::NewHandle(bytesNeeded);
  418. #endif
  419. #ifdef FW_BUILD_WIN
  420.     aSystemHandle = ::GlobalAlloc(GMEM_MOVEABLE, bytesNeeded);
  421. #endif
  422.     
  423.     if (aSystemHandle == 0)
  424.         FW_THROW(FW_XMemoryExhausted(bytesNeeded));
  425.  
  426.     return aSystemHandle;
  427. }
  428.  
  429. //----------------------------------------------------------------------------------------
  430. // FW_CMemoryManager::ResizeSystemHandle - 
  431. //----------------------------------------------------------------------------------------
  432. FW_PlatformHandle FW_CMemoryManager::ResizeSystemHandle(FW_PlatformHandle aHandle,
  433.                                                         unsigned long bytesNeeded)
  434. {
  435.     FW_LOG_OR_TRIGGER_EXCEPTION(FW_XMemoryExhausted, FW_XMemoryExhausted(bytesNeeded));
  436.  
  437.     FW_ASSERT(aHandle != 0);
  438.  
  439. FW_PlatformHandle newHandle = aHandle;
  440.  
  441. #ifdef FW_BUILD_MAC
  442.     ::SetHandleSize(aHandle, bytesNeeded);
  443. #endif
  444. #ifdef FW_BUILD_WIN
  445.     newHandle = ::GlobalReAlloc(aHandle, bytesNeeded, GMEM_MOVEABLE);
  446. #endif
  447.     
  448.     if (GetSystemHandleSize(newHandle) < bytesNeeded)
  449.         FW_THROW(FW_XMemoryExhausted( bytesNeeded));
  450.  
  451.     return newHandle;
  452. }
  453.  
  454. //----------------------------------------------------------------------------------------
  455. // FW_CMemoryManager::FreeSystemHandle - 
  456. //----------------------------------------------------------------------------------------
  457. void FW_CMemoryManager::FreeSystemHandle(FW_PlatformHandle aHandle)
  458. {
  459.     FW_ASSERT(aHandle != 0);
  460.  
  461. #ifdef FW_BUILD_MAC
  462.     ::DisposHandle(aHandle);
  463. #endif
  464. #ifdef FW_BUILD_WIN
  465.     ::GlobalFree(aHandle);
  466. #endif
  467. }
  468.  
  469. //----------------------------------------------------------------------------------------
  470. // FW_CMemoryManager::LockSystemHandle - 
  471. //----------------------------------------------------------------------------------------
  472. void * FW_CMemoryManager::LockSystemHandle(FW_PlatformHandle handle)
  473. {
  474.     FW_ASSERT(handle != 0);
  475.  
  476.     void* memory;
  477.     
  478. #ifdef FW_BUILD_MAC
  479.     HLock(handle);
  480.     memory = *handle;
  481. #endif
  482. #ifdef FW_BUILD_WIN
  483.     memory = ::GlobalLock(handle);
  484. #endif
  485.  
  486.     if(memory == NULL)
  487.         FW_THROW(FW_XMemoryExhausted());
  488.         
  489.     return memory;
  490. }
  491.  
  492. //----------------------------------------------------------------------------------------
  493. // FW_CMemoryManager::UnlockSystemHandle - 
  494. //----------------------------------------------------------------------------------------
  495. void FW_CMemoryManager::UnlockSystemHandle(FW_PlatformHandle aHandle)
  496. {
  497.     FW_ASSERT(aHandle != 0);
  498.     
  499. #ifdef FW_BUILD_MAC
  500.     ::HUnlock(aHandle);
  501. #endif
  502. #ifdef FW_BUILD_WIN
  503.     ::GlobalUnlock(aHandle);
  504. #endif
  505. }
  506.  
  507. //----------------------------------------------------------------------------------------
  508. // FW_CMemoryManager::GetSystemHandleSize - 
  509. //----------------------------------------------------------------------------------------
  510. unsigned long FW_CMemoryManager::GetSystemHandleSize(FW_PlatformHandle aHandle)
  511. {
  512.     FW_ASSERT(aHandle != 0);
  513.     
  514. #ifdef FW_BUILD_MAC
  515.     return ::GetHandleSize(aHandle);
  516. #endif
  517. #ifdef FW_BUILD_WIN
  518.     return ::GlobalSize(aHandle);
  519. #endif
  520. }
  521.  
  522. //----------------------------------------------------------------------------------------
  523. // FW_CMemoryManager::CopySystemHandle - 
  524. //----------------------------------------------------------------------------------------
  525. FW_PlatformHandle FW_CMemoryManager::CopySystemHandle(FW_PlatformHandle aHandle)
  526. {
  527.     unsigned long size = GetSystemHandleSize(aHandle);
  528.  
  529.     FW_CAcquireLockedSystemHandle<void> sourceLock(aHandle);
  530.     void *sourcePointer = sourceLock.GetPointer();
  531.  
  532.     FW_PlatformHandle newHandle = AllocateSystemHandle(size);
  533.     FW_CAcquireLockedSystemHandle<void> destinationLock(newHandle);
  534.     void *destinationPointer = destinationLock.GetPointer();
  535.  
  536.     CopyMemory(sourcePointer, destinationPointer, size);
  537.  
  538.     return newHandle;
  539. }
  540.  
  541. #ifdef FW_NEW_AND_DELETE_NOT_DISABLED
  542.  
  543. // Currently parts must use OpenDoc's new and delete to avoid mismatching new and delete
  544. // calls in certain situations. Will be fixed soon.
  545.  
  546. //========================================================================================
  547. // C++ Global operator new & delete
  548. //========================================================================================
  549.  
  550. //----------------------------------------------------------------------------------------
  551. // operator new
  552. //----------------------------------------------------------------------------------------
  553. #ifdef __BORLANDC__
  554. void* cdecl operator new(size_t size)
  555. #else
  556. void*       operator new(size_t size)
  557. #endif
  558. {
  559.  
  560.     FW_SPrivMemoryGlobals& globals = FW_CMemoryTaskGlobals::GetMemoryGlobals();
  561.     void* p;
  562.     
  563.     globals.gLastRequested = size;
  564.     
  565.     while ((p = FW_CMemoryManager::PrimitiveAllocateBlock(size)) == 0)
  566.     {
  567.         if (globals.gNewHandler)
  568.             (*(globals.gNewHandler))();
  569.         else
  570.             return 0;
  571.     }
  572.  
  573.     return p;
  574. }
  575.  
  576. //----------------------------------------------------------------------------------------
  577. // operator delete
  578. //----------------------------------------------------------------------------------------
  579. #ifdef __BORLANDC__
  580. void cdecl operator delete(void *pObject)
  581. #else
  582. void       operator delete(void *pObject)
  583. #endif
  584. {
  585.     FW_CMemoryManager::FreeBlock(pObject);
  586. }
  587.  
  588. #endif
  589.